home *** CD-ROM | disk | FTP | other *** search
- /* -----------------------------------------------------------------------------
-
- button.api ©1999 Dietmar Eilert
-
- Plug-in example. This plug-in opens a container and shows a gadget.
-
- DMAKE
-
- -------------------------------------------------------------------------------
-
- */
-
- #include "defs.h"
-
- /// "prototypes"
-
- // library functions
-
- Prototype LibCall struct APIClient *APIMountClient(__A0 struct APIMessage *, __A1 char *);
- Prototype LibCall void APICloseClient(__A0 struct APIClient *, __A1 struct APIMessage *);
- Prototype LibCall void APIBriefClient(__A0 struct APIClient *, __A1 struct APIMessage *);
- Prototype LibCall void APIFree (__A0 struct APIClient *, __A1 struct APIOrder *);
-
- // private functions
-
- Prototype ULONG DispatchContainer(struct APIClient *, struct APIMessage *);
- Prototype ULONG AttachGadgets (struct PlugInContext *, struct APIMessage *);
- Prototype ULONG DetachGadgets (struct PlugInContext *, struct APIMessage *);
-
- ///
- /// "defines"
-
- // we allocate a context structure for each instance of this client to store local data
-
- struct PlugInContext {
-
- struct APIClient APIClient; // API handle (exposed to host)
- struct Gadget *Context; // private data: gadget list
- UWORD Gadgets; // private data: gadget counter
- };
-
- ///
- /// "library functions"
-
- LibCall struct APIClient *
- APIMountClient(__A0 struct APIMessage *apiMsg, __A1 char *args)
- {
- struct PlugInContext *context;
-
- // build a description of this client (host will pass this back to us as "handle" during subsequent library calls)
-
- if (context = (struct PlugInContext *)AllocVec(sizeof(struct PlugInContext), MEMF_ANY | MEMF_CLEAR)) {
-
- if (context->APIClient.api_Area = (struct APIArea *)AllocVec(sizeof(struct APIArea), MEMF_ANY | MEMF_CLEAR)) {
-
- // client description
-
- context->APIClient.api_APIVersion = API_INTERFACE_VERSION;
- context->APIClient.api_Version = 1;
- context->APIClient.api_Name = "Button";
- context->APIClient.api_Info = "Plug-in example";
- context->APIClient.api_Commands = NULL;
- context->APIClient.api_Serial = 0;
- context->APIClient.api_Classes = API_CLASS_SYSTEM | API_CLASS_CONTAINER;
-
- // prepare the container request
-
- context->APIClient.api_Area->api_Width = 20;
- context->APIClient.api_Area->api_Height = 5;
- context->APIClient.api_Area->api_UnitsX = API_UNITS_FONT;
- context->APIClient.api_Area->api_UnitsY = API_UNITS_FONT;
- context->APIClient.api_Area->api_Alignment = API_ALIGN_RIGHT;
- context->APIClient.api_Area->api_Style = API_STYLE_STANDARD;
- context->APIClient.api_Area->api_IDCMP = IDCMP_GADGETUP;
- }
- else {
-
- FreeVec(context);
-
- context = NULL;
- }
- }
-
- return((struct APIClient *)context);
- }
-
- LibCall void
- APICloseClient(__A0 struct APIClient *handle, __A1 struct APIMessage *apiMsg)
- {
- // free ressources related to this client
-
- FreeVec(handle->api_Area);
-
- FreeVec(handle);
- }
-
- LibCall void
- APIBriefClient(__A0 struct APIClient *handle, __A1 struct APIMessage *apiMsg)
- {
- struct APIMessage *msg;
-
- // handle host's command notify
-
- for (msg = apiMsg; msg; msg = msg->api_Next) {
-
- if (msg->api_State == API_STATE_NOTIFY) {
-
- switch (msg->api_Class) {
-
- case API_CLASS_CONTAINER:
-
- msg->api_Error = DispatchContainer(handle, msg);
-
- break;
-
- case API_CLASS_SYSTEM:
-
- msg->api_Error = API_ERROR_OK;
-
- break;
-
- default:
-
- msg->api_Error = API_ERROR_UNKNOWN;
- }
- }
- }
- }
-
-
- LibCall void
- APIFree(__A0 struct APIClient *handle, __A1 struct APIOrder *apiOrder)
- {
- struct APIOrder *order, *next;
-
- // free data allocated for orders sent to host
-
- for (order = apiOrder; order; order = next) {
-
- next = order->api_Next;
-
- switch (order->api_Flags) {
-
- case API_ORDER_DETACH:
-
- FreeGadgets((struct Gadget *)order->api_Data);
-
- break;
- }
-
- FreeVec(order);
- }
- }
-
- ///
- /// "private functions"
-
- /* ----------------------------- DispatchContainer -----------------------------
-
- Handle container-related event
-
- */
-
- ULONG
- DispatchContainer(handle, apiMsg)
-
- struct APIClient *handle;
- struct APIMessage *apiMsg;
- {
- ULONG error = API_ERROR_OK;
-
- switch (apiMsg->api_Action) {
-
- case API_ACTION_DETACH:
-
- // request to detach gadgets from window
-
- error = DetachGadgets((struct PlugInContext *)handle, apiMsg);
-
- break;
-
- case API_ACTION_ATTACH:
-
- // request to attach gadgets
-
- error = AttachGadgets((struct PlugInContext *)handle, apiMsg);
-
- break;
-
- case API_ACTION_PAINT:
-
- // paint user interface
-
- {
- struct PlugInContext *context = (struct PlugInContext *)handle;
-
- if (context->Context)
-
- RefreshGList(context->Context, apiMsg->api_Instance->api_Window, NULL, context->Gadgets);
- }
-
- break;
-
- case API_ACTION_REFRESH:
-
- // refresh the user interface (nothing to do here: gadgets are refreshed automatically)
-
- break;
-
- case API_ACTION_INPUTEVENT:
-
- // input event to be handled
-
- struct APIInputEvent *event;
-
- if (event = (struct APIInputEvent *)apiMsg->api_Data) {
-
- switch (event->api_IDCMPClass) {
-
- case IDCMP_GADGETUP:
-
- {
- // is this event meant for our window ?
-
- if (event->api_IDCMPWindow == apiMsg->api_Instance->api_Window) {
-
- struct Gadget *gadget = (struct Gadget *)event->api_IDCMPAddress;
-
- // one of our gadgets ?
-
- if (gadget->GadgetID == apiMsg->api_Instance->api_Container->api_Namespace) {
-
- apiMsg->api_Status = "Gadget event detected by plug-in !";
-
- // no further processing of this input event required
-
- apiMsg->api_State = API_STATE_CONSUMED;
- }
- }
- }
-
- break;
- }
- }
-
- break;
-
- default:
-
- error = API_ERROR_UNKNOWN;
- }
-
- return(error);
- }
-
-
- /* ------------------------------- DetachGadgets -------------------------------
-
- Detach gadgets from window
-
- */
-
- ULONG
- DetachGadgets(context, apiMsg)
-
- struct PlugInContext *context;
- struct APIMessage *apiMsg;
- {
- // any gadgets attached to window ?
-
- if (context->Context) {
-
- // prepare order to send a command ("detach these gadgets from the window") to the host
-
- if (apiMsg->api_Order = (struct APIOrder *)AllocVec(sizeof(struct APIOrder), MEMF_PUBLIC | MEMF_CLEAR)) {
-
- // create order for host to have gadgets detached
-
- apiMsg->api_Order->api_Flags = API_ORDER_DETACH;
-
- apiMsg->api_Order->api_Data = context->Context;
-
- // gadgets now assumed to be detached from window
-
- context->Context = NULL;
-
- // see APIFree() function for further processing (disposal of gadget list)
- }
- }
-
- return(API_ERROR_OK);
- }
-
-
- /* ------------------------------- AttachGadgets -------------------------------
-
- Attach gadgets to window
-
- */
-
- ULONG
- AttachGadgets(context, apiMsg)
-
- struct PlugInContext *context;
- struct APIMessage *apiMsg;
- {
- ULONG error;
-
- // already attached to window ?
-
- if (context->Context) {
-
- error = API_ERROR_OK;
- }
- else {
-
- struct APIContainer *container;
-
- error = API_ERROR_FAIL;
-
- if (container = apiMsg->api_Instance->api_Container) {
-
- // container not fully obscured ?
-
- if (container->api_Clipping) {
-
- UWORD x0;
- UWORD y0;
- UWORD x1;
- UWORD y1;
- UWORD w;
- UWORD h;
-
- // determine space available for gadgets
-
- x0 = container->api_Clipping->MinX;
- y0 = container->api_Clipping->MinY;
- x1 = container->api_Clipping->MaxX;
- y1 = container->api_Clipping->MaxY;
-
- // center gadget in container
-
- w = (x1 - x0 + 1) / 2;
- h = (y1 - y0 + 1) / 2;
-
- x0 += (w / 2);
- y0 += (h / 2);
-
- if ((w >= 2) && (h >= 2)) {
-
- struct Gadget *gadget;
- UBYTE *label;
- UWORD labelsize;
-
- label = "button";
-
- // does label fit into gadget ?
-
- labelsize = TextLength(container->api_RPort, label, strlen(label));
-
- if (container->api_TextAttr->ta_YSize > h) {
-
- label = NULL;
- }
- else if (labelsize > w)
-
- label = NULL;
-
- // create the gadget
-
- if (gadget = CreateContext(&context->Context)) {
-
- static struct TagItem tags[] = { GT_Underscore, '_', TAG_DONE };
-
- struct NewGadget ng;
-
- ng.ng_GadgetText = label;
- ng.ng_LeftEdge = x0;
- ng.ng_TopEdge = y0;
- ng.ng_Width = w;
- ng.ng_Height = h;
- ng.ng_VisualInfo = container->api_VisualInfo;
- ng.ng_GadgetID = container->api_Namespace;
- ng.ng_TextAttr = container->api_TextAttr;
- ng.ng_Flags = PLACETEXT_IN;
- ng.ng_UserData = context;
-
- if (gadget = CreateGadgetA(BUTTON_KIND, gadget, &ng, tags)) {
-
- // count gadgets (result may differ from the logical gadget count for some gadtools types)
-
- context->Gadgets = 0;
-
- for (gadget = context->Context; gadget; gadget = gadget->NextGadget)
-
- ++context->Gadgets;
-
- // create order for host to have gadgets added to the window
-
- if (apiMsg->api_Order = (struct APIOrder *)AllocVec(sizeof(struct APIOrder), MEMF_PUBLIC | MEMF_CLEAR)) {
-
- apiMsg->api_Order->api_Flags = API_ORDER_ATTACH;
-
- apiMsg->api_Order->api_Data = context->Context;
-
- // set return code
-
- error = API_ERROR_OK;
- }
- else {
-
- FreeGadgets(context->Context);
-
- context->Context = NULL;
- context->Gadgets = 0;
- }
- }
- }
- }
- }
- }
- }
-
- return(error);
- }
-
- ///
-